﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;

namespace ZThing
{
    public partial class Form1 : Form
    {
       
       string mapscript;
        int X=0, Y=0;
        string[] tileset;
        PictureBox[] pb = new PictureBox[100];
        PictureBox[,] pb2D = new PictureBox[10, 10];
        Random rnd = new Random();
        string[] maps = {};
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            if (!Directory.Exists("maps")) Directory.CreateDirectory("maps");
            if (!Directory.Exists("textures/UI/avatars")) Directory.CreateDirectory("textures/UI/avatars");
            if (!Directory.Exists("textures/UI")) Directory.CreateDirectory("textures/UI");
            if (!Directory.Exists("scripts")) { MessageBox.Show("Scripts are missing!"); Application.ExitThread(); }
            if (!Directory.Exists("scripts/missions")) { Directory.CreateDirectory("scripts/missions"); }
            if (!File.Exists("textures.id")) { MessageBox.Show("Texture IDs are missing!"); Application.ExitThread(); }
            
            if (!Directory.Exists("textures")) { MessageBox.Show("Textures are missing!"); Application.ExitThread(); }
            maps = Directory.GetFiles(@"maps", "*.dat");
            foreach(string map in maps)
            {
                listBox1.Items.Add(map.ToString());
            }

            try { C_Avatar.BackgroundImage = Image.FromFile("textures/UI/avatars/default-avatar.png"); }
            catch { }
            try { C_Panel.BackgroundImage = Image.FromFile("textures/UI/panel.png"); }
            catch { C_Panel.BackColor = Color.Blue; }

            C_Avatar.BackgroundImageLayout = ImageLayout.Stretch;
        }

        void Start(string mapname)
        {
            listBox1.Hide();
            button1.Hide();
            button2.Hide();
            this.BackgroundImage = Image.FromFile(@"textures\000a.png");
            this.BackgroundImageLayout = ImageLayout.Tile;
            //MessageBox.Show(mapname);
             this.BackgroundImage = Image.FromFile("textures/000.png");
            this.BackgroundImageLayout = ImageLayout.Tile;
            tileset = File.ReadAllLines("textures.id");
            string[] mapped0 = mapname.Split('\\');
            string[] mapped1 = mapped0[1].Split('.');
            if(!File.Exists("scripts/missions/"+mapped1[0]+".stp"))
            {
                File.Create("scripts/missions/" + mapped1[0] + ".stp").Close();
                mapscript = "scripts/missions/" + mapped1[0] + ".stp";
                using (StreamWriter sw = new StreamWriter("scripts/missions/" + mapped1[0] + ".stp",true))
                {
                    sw.WriteLine("#Map: "+mapname);
                    sw.WriteLine("[MAIN]");
                    sw.WriteLine("return;");
                }
            }
            mapscript = "scripts/missions/" + mapped1[0] + ".stp";
            int pbC = 0;
            string[] tiles = File.ReadAllLines(mapname);
            string[] map = { };
            

            for (int y = 0; y < 10; y++)
            {
                try { map = tiles[y].Split(' '); }
                catch { MessageBox.Show("Map is corrupted![0]"); Application.ExitThread(); break; }
                for (int x = 0; x < 10; x++)
                {
                    pb[pbC] = new PictureBox();
                    pb[pbC].Location = new Point(X, Y);
                    pb[pbC].Size = new Size(64, 64);
                    pb[pbC].BackColor = Color.Transparent;
                    pb[pbC].BorderStyle = BorderStyle.None;
                    pb[pbC].BackgroundImage = Image.FromFile(@"textures/000.png");
                    pb[pbC].Tag = "000.png";
                    pb[pbC].MouseClick += PBox;
                    switch (map[x])
                    {
                        case "0":
                            int rand = rnd.Next(0, 4);
                            if (rand == 0) pb[pbC].BackgroundImage = Image.FromFile(@"textures\000.png");
                            else pb[pbC].BackgroundImage = Image.FromFile(@"textures\000a.png"); ;
                            break;
                        default:
                            try
                            {
                                string[] id = {};
                                for (int ai = 0; ai < tileset.Length; ai++)
                                {
                                    id = tileset[ai].Split(' ');
                                    if (map[x] == id[0])
                                    {
                                        pb[pbC].BackgroundImage = Image.FromFile(@"textures/" + id[1].ToString());
                                        pb[pbC].Tag = id[1];
                                        //break;
                                    }

                                }
                            }
                            catch (Exception ex)
                            {

                                MessageBox.Show("Map is incorrectly defined! Syntax error at tile: " + y + ":" + x);
                                Application.ExitThread();
                            }
                            break;
                    }
                    this.Controls.Add(pb[pbC]);
                    pb2D[x, y] = pb[pbC];
                    X += 64;
                    pbC++;
                }
                X = 0;
                Y += 64;
            }
            Script(mapscript);
            }

        private void PBox(object sender, MouseEventArgs e)
        {
            
        }
        
        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            MessageBox.Show("aa");
            for (int yy = 0; yy < 10; yy++)
            {
                for (int xx = 0; xx < 10; xx++)
                {
                    
                    int rand = rnd.Next(0, 4);
                    if (rand == 0) g.DrawImage(Image.FromFile(@"textures\000.png"), 0, 0, 64, 64);
                    else g.DrawImage(Image.FromFile(@"textures\000a.png"), 0, 0, 64, 64) ;


                    

                    X += 64;
                    //this.Controls.SetChildIndex(this, xx);
                    

                }
                Y += 64;
                X = 0;
            }
        }

        private void listBox1_DoubleClick(object sender, EventArgs e)
        {
            try
            {
                Start(listBox1.SelectedItem.ToString());
            }
            catch { }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Form2 dlg = new Form2();
            dlg.ShowDialog();
            for (int i = 0; i < listBox1.Items.Count; i++)
			{
                listBox1.Items.RemoveAt(i);
			}
            
            if (!Directory.Exists("maps")) Directory.CreateDirectory("maps");
            if (!File.Exists("textures.id")) { MessageBox.Show("Texture IDs are missing!"); Application.ExitThread(); }
            if (!Directory.Exists("textures")) { MessageBox.Show("Textures are missing!"); Application.ExitThread(); }
            maps = Directory.GetFiles(@"maps", "*.dat");
            foreach (string map in maps)
            {
                listBox1.Items.Add(map.ToString());
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                if (listBox1.SelectedItem.ToString() != "")
                {
                    Form3 dlg = new Form3(listBox1.SelectedItem.ToString());
                    dlg.Show();
                }
            }
            catch { }
        }
        bool? present = null;
        int[] volania = new int[4096];
        void Script(string mapscript)
        {
            for (int dynmap = 0; dynmap < volania.Length; dynmap++)
            {
                volania[dynmap] = -1;
            }
            string[] code = File.ReadAllLines(mapscript);
            string[] content = new string[50000];
            int codeOffset = 50001;
            int contentOffset = 0;
            for (int i = 0; i < code.Length; i++)
            {
                if(code[i].ToCharArray()[0] == '#' && code[i].ToCharArray()[1] == ':')
                {
                    string[] vol = code[i].Split(':');
                    for (int ii = 1; ii < vol.Length; ii++)
                    {
    
                        volania[Convert.ToInt32(vol[ii])] = Convert.ToInt32(vol[ii]);
                    }
                }
                if(code[i].ToUpper()=="[MAIN]")
                {
                    codeOffset = i + 1;
                }
                if(i >= codeOffset)
                {
                    content[contentOffset] = code[i];
                    contentOffset++;
                    
                }
            }
            
            try {
                for (int i = 0; i < content.Length; i++)
                {
                    present = null;
                    string[] cmd = content[i].Split('=');

                    if (volania[i] != i)
                    {
                        i = ProceedS(cmd, i);
                        volania[i] = i;
                    }
                    if (code[i].ToLower() == "return;")
                        break;
                }
            }
            catch {  }

        }
        int ProceedS(string[] cmds, int cmdC)
        {
            present = null;
            volania[cmdC] = cmdC;
            string[] cmd = cmds;
            switch (cmd[0].ToLower())
            {
                case "chat":
                    bool result = false;
                    string resultVar = "";
                    string resultVar2 = "";
                    try
                    {

                        string[] data = cmd[1].Split('|');
                        C_Dialog.Text = data[0];
                        if (data[1] != "") C_Confirm.Text = data[1];
                        if (data[2] != "") C_Decline.Text = data[2];
                        try { if (data[3] != "") C_Avatar.BackgroundImage = Image.FromFile("textures/UI/avatars/" + data[3]); }
                        catch { C_Avatar.BackgroundImage = Image.FromFile("textures/UI/avatars/default-avatar.png"); }
                        
                        try { if (data[4] != "") result = Convert.ToBoolean(data[4]); }
                        catch { result = false; }
                        if (data[5] != "") resultVar = data[5];
                        if (data[6] != "") resultVar2 = data[6];
                    }
                    catch { C_Dialog.Text = cmd[1]; }
                    C_Panel.Show();
                    while (present == null)
                    { Application.DoEvents(); }
                    if (result == present)
                    {
                        int volanie = Convert.ToInt32(resultVar);
                        volania[volanie] = -1;
                        cmdC = volanie-1;
                    }
                    else {
                        int volanie = Convert.ToInt32(resultVar2);
                        volania[volanie] = -1;
                        cmdC = volanie - 1;
                    }
                    
                    break;
                case "sleep":
                    System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
                    timer.Interval = Convert.ToInt32(cmd[1]);
                    timer.Tick += timer_Tick;
                    timer.Start();
                    while(present==null)
                    {
                        Application.DoEvents();
                    }
                    timer.Stop();
                    timer = null;
                    break;
                case "goto":
                    cmdC = Convert.ToInt32(cmd[1]) - 1;
                    break;
                case "draw":
                    try
                    {
                        string[] data = cmd[1].Split('|');
                        int x = Convert.ToInt32(data[0]);
                        int y = Convert.ToInt32(data[1]);
                        int sum = x * y;
                        pb[sum].Image = Image.FromFile("textures/"+data[2]);
                        
                    }
                    catch(Exception ex) {MessageBox.Show(ex.ToString()); }
                    break;
                case "undraw":
                    try
                    {
                        string[] data = cmd[1].Split('|');
                        int x = Convert.ToInt32(data[0]);
                        int y = Convert.ToInt32(data[1]);
                        int sum = x * y;
                        pb[sum].Image = null;

                    }
                    catch (Exception ex) { MessageBox.Show(ex.ToString()); }
                    break;
                case "walk":
                    try
                    {
                        string[] data = cmd[1].Split('|');
                        int x = Convert.ToInt32(data[0]);
                        int y = Convert.ToInt32(data[1]);
                        int x2 = Convert.ToInt32(data[2]);
                        int y2 = Convert.ToInt32(data[3]);
                        
                        pb2D[x,y].Image = null;
                        pb2D[x,y].Image = Image.FromFile("textures/" + data[4]);
                        string img = ("textures/" + data[4]);
                        string road = data[5];
                        string[] roadiness = road.Split('/');
                        //Behaviour

                        //On road
                        int _x = x, _y = y;
                        bool horiz, vert, up = true, down = true;
                        while(true)
                        {
                            Application.DoEvents();
                            if (x > x2) horiz = true; else horiz = false;
                            if (y > y2) vert = true; else vert = false;
                        if(_x!=x2)
                            if(horiz)
                            {
                                string tmp = pb2D[_x - 1, _y].Tag.ToString();
                                string[] dtmp = tmp.Split('/');
                                if(dtmp[0] == roadiness[0])
                                {
                                    pb2D[_x, _y].Image = null;
                                    pb2D[_x - 1, _y].Image = Image.FromFile(img);
                                    _x = _x - 1;
                                    down = false;

                                }
                                else
                                {

                                    if (down)
                                    {
                                        if (_y + 1 >= 11) { down = false; break; }
                                        pb2D[_x, _y].Image = null;
                                        pb2D[_x, _y + 1].Image = Image.FromFile(img);
                                        _y += 1;
                                    }
                                    else if (up)
                                    {
                                        if (_y - 1 >= -1) { up = false; break; }
                                        pb2D[_x, _y].Image = null;
                                        pb2D[_x, _y - 1].Image = Image.FromFile(img);
                                        _y += -1;
                                    }

                                }
                            }
                            else
                            {
                                string tmp = pb2D[_x + 1, _y].Tag.ToString();
                                string[] dtmp = tmp.Split('/');
                                if (dtmp[0] == roadiness[0])
                                {
                                    pb2D[_x, _y].Image = null;
                                    pb2D[_x+1, _y].Image = Image.FromFile(img);
                                    _x = _x + 1;
                                    down = false;
                                }
                                else {

                                    if (down)
                                    {
                                        if (_y + 1 >= 11) { down = false; break; }
                                        pb2D[_x, _y].Image = null;
                                        pb2D[_x, _y + 1].Image = Image.FromFile(img);
                                        _y += 1;
                                    }
                                    else if (up)
                                    {
                                        if (_y - 1 >= -1) { up = false; break; }
                                        pb2D[_x, _y].Image = null;
                                        pb2D[_x, _y - 1].Image = Image.FromFile(img);
                                        _y += -1;
                                    }

                                }
                            }
                        if(_y!=y2)
                            if (vert)
                            {
                                string tmp = pb2D[_x, _y - 1].Tag.ToString();
                                string[] dtmp = tmp.Split('/');
                                if (dtmp[0] == roadiness[0])
                                {
                                    pb2D[_x, _y].Image = null;
                                    pb2D[_x, _y - 1].Image = Image.FromFile(img);
                                    _y = _y - 1;
                                }
                            }
                            else
                            {
                                string tmp = pb2D[_x, _y + 1].Tag.ToString();
                                string[] dtmp = tmp.Split('/');
                                if (dtmp[0] == roadiness[0])
                                {
                                    pb2D[_x, _y].Image = null;
                                    pb2D[_x, _y + 1].Image = Image.FromFile(img);
                                    _y = _y + 1;
                                }
                            }
                            
                            if (_x == x2 && _y == y2) break;
                            Thread.Sleep(100);
                        }
                    }
                    catch (Exception ex) { MessageBox.Show(ex.ToString()); }
                    break;
                case "repeat":
                    volania[atoi(cmd[1])] = -1;
                    cmdC = atoi(cmd[1]) -1;
                    break;
                case "unlock":
                    volania[atoi(cmd[1])] = -1;
                    break;
                case "lock":
                    volania[atoi(cmd[1])]=atoi(cmd[1]);
                    break;
                case "exit":
                    Application.ExitThread();
                    break;
                case "message":
                    try
                    {
                        string[] data = cmd[1].Split('|');
                        MessageBox.Show(data[0], data[1]);
                    }
                    catch { MessageBox.Show(cmd[1]); }
                    break;
                default:
                    if (cmd[0].ToLower() == "return;" || cmd[0].StartsWith("#", StringComparison.OrdinalIgnoreCase)) break;
                    MessageBox.Show("[Line: " + cmdC + "] Unknown command '" + cmd[0] + "' found.");
                    break;

            }
            return cmdC;
        }
        int atoi(string str)
        {
            return Convert.ToInt32(str);
        }
        void timer_Tick(object sender, EventArgs e)
        {
            present = true;
            
        }
        private void C_Confirm_Click(object sender, EventArgs e)
        {
            C_Panel.Hide();
            present = true;
        }

        private void C_Decline_Click(object sender, EventArgs e)
        {
            C_Panel.Hide();
            present = false;
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            Application.ExitThread();
        }
    }
}
